package com.rxst.msg.server.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rxst.msg.dto.save.menu.UpdateMenuAuthDto;
import com.rxst.msg.dto.search.MsgxMenuSearchDto;
import com.rxst.msg.entity.MsgxMenuEntity;
import com.rxst.msg.entity.MsgxUserMenuEntity;
import com.rxst.msg.mapper.MsgxMenuMapper;
import com.rxst.msg.server.MsgxMenuService;
import com.rxst.msg.server.MsgxUserMenuService;
import com.rxst.msg.sso.entity.UserContext;
import com.rxst.msg.vo.MsgxMenuVo;
import com.rxst.msg.vo.menu.MenuFunctionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 设备授权表
 *
 * @author rxst
 * @email rxst@gmail.com
 * @date 2021-08-19 11:47:00
 */
@Service("msgxMenuService")
@Transactional(rollbackFor = Exception.class)
public class MsgxMenuServiceImpl extends ServiceImpl<MsgxMenuMapper, MsgxMenuEntity> implements MsgxMenuService {

    @Autowired
    private MsgxMenuMapper mapper;

    @Autowired
    private MsgxUserMenuService userMenuService;

    @Override
    public List<MsgxMenuVo> list(MsgxMenuSearchDto vo) {
        return mapper.list(vo);
    }

    @Override
    public PageInfo<MsgxMenuVo> page(MsgxMenuSearchDto vo) {
        PageHelper.startPage(vo.getCurrent(), vo.getSize());
        PageInfo<MsgxMenuVo> page = new PageInfo<>(mapper.list(vo));
        return page;
    }

    @Override
    public Boolean saveEntity(MsgxMenuEntity t) {
        t.setMenuId(IdUtil.fastSimpleUUID());
        return save(t);
    }

    @Override
    public Boolean saveEntityBatch(List<MsgxMenuEntity> list) {
        if (CollUtil.isNotEmpty(list)) {
            for (MsgxMenuEntity entity : list) {
                //todo
            }
            return saveBatch(list);
        }
        return false;
    }

    @Override
    public Boolean updateEntity(MsgxMenuEntity t) {
        return updateById(t);
    }

    @Override
    public Boolean updateEntityBatch(List<MsgxMenuEntity> list) {
        if (CollUtil.isNotEmpty(list)) {
            for (MsgxMenuEntity entity : list) {
                //todo
            }
            return updateBatchById(list);
        }
        return false;
    }

    @Override
    public void deleteLogic(Long id) {
        mapper.deleteLogic(id);
    }

    @Override
    public void deleteLogicByIds(List<Long> ids) {
        mapper.deleteLogicByIds(ids);
    }

    /**
     * 编辑用户权限列表
     */
    @Override
    public void updateMenuByUserId(UpdateMenuAuthDto menuAuthDto) {

        //删除用户权限数据
        QueryWrapper<MsgxUserMenuEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", menuAuthDto.getUserId());
        userMenuService.remove(queryWrapper);

        //将对应的数据插入
        List<String> menuList = menuAuthDto.getMenuList();
        List<MsgxUserMenuEntity> userMenuList = new ArrayList<>();
        if (CollUtil.isNotEmpty(menuList)) {
            for (String menuId : menuList) {
                MsgxUserMenuEntity msgxUserMenuEntity = new MsgxUserMenuEntity();
                msgxUserMenuEntity.setMenuId(menuId);
                msgxUserMenuEntity.setUserId(menuAuthDto.getUserId());
                msgxUserMenuEntity.setUserMenuId(UUID.randomUUID().toString());
                userMenuList.add(msgxUserMenuEntity);
            }
        }
        if (userMenuList.size() > 0) {
            userMenuService.saveBatch(userMenuList);
        }
    }

    @Override
    public List<MenuFunctionVo> tree(String userId) {
        ArrayList<MenuFunctionVo> menuList = new ArrayList<>();
        HashMap<String, MenuFunctionVo> map = new HashMap<>();
        if (StrUtil.isBlank(userId)) {
            UserContext userContext = UserContext.getUserContext();
            if (userContext == null) {
                return menuList;
            }
            userId = userContext.getCurrentUserId();
        }
        // 查询用户菜单权限
        LambdaQueryChainWrapper<MsgxUserMenuEntity> wrapper = userMenuService.lambdaQuery();
        wrapper.eq(MsgxUserMenuEntity::getUserId, userId);
        List<MsgxUserMenuEntity> userMenuEntityList = wrapper.list();
        Map<String, MsgxUserMenuEntity> menuEntityMap = new HashMap<>();
        if (CollUtil.isNotEmpty(userMenuEntityList)) {
            for (MsgxUserMenuEntity entity : userMenuEntityList) {
                if (!menuEntityMap.containsKey(entity.getMenuId())) {
                    menuEntityMap.put(entity.getMenuId(), entity);
                }
            }
        }
        // 查询所有菜单，有权限的为true
        LambdaQueryChainWrapper<MsgxMenuEntity> lambdaQuery = this.lambdaQuery();
        lambdaQuery.orderByAsc(MsgxMenuEntity::getMenuType).orderByAsc(MsgxMenuEntity::getCreateTime);
        List<MsgxMenuEntity> list = lambdaQuery.list();
        for (MsgxMenuEntity entity : list) {
            if (menuEntityMap.containsKey(entity.getMenuId())) {
                entity.setMenuAuth(true);
            } else {
                entity.setMenuAuth(false);
            }
            if (entity.getMenuType() == 1) {
                MenuFunctionVo functionVo = new MenuFunctionVo();
                functionVo.setParentName(entity.getMenuName());
                functionVo.setParentId(entity.getMenuId());
                functionVo.setMenuAuth(entity.getMenuAuth());
                functionVo.setMenuUrl(entity.getMenuUrl());
                functionVo.setMenuIcon(entity.getMenuIcon());
                List<MsgxMenuEntity> voList = new ArrayList<>();
                functionVo.setChildren(voList);
                map.put(entity.getMenuId(), functionVo);
            } else {
                MenuFunctionVo functionVo = map.get(entity.getMenuParentId());
                List<MsgxMenuEntity> children = functionVo.getChildren();
                children.add(entity);
            }
        }
        menuList.add(map.get("1"));
        menuList.add(map.get("2"));
        menuList.add(map.get("28"));
        menuList.add(map.get("18"));
        menuList.add(map.get("3"));
        return menuList;
    }
}

